package com.authine.cloudpivot.web.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.common.utils.StringUtils;
import com.authine.cloudpivot.web.api.dao.HEMSHospitalMapper;
import com.authine.cloudpivot.web.api.service.HospitalService;
import com.authine.cloudpivot.web.api.utils.DateUtils;
import com.authine.cloudpivot.web.api.utils.HttpClients;
import com.authine.cloudpivot.web.api.vo.HEMSHospital;
import com.authine.cloudpivot.web.api.vo.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * ClassName: HospitalServiceImpl <br/>
 * Description: 医院基本信息添加或更新<br/>
 * date: 2020/8/25 11:21<br/>
 * @author fj<br />
 * @since JDK 1.8
 */

@Slf4j
@Service
public class HospitalServiceImpl implements HospitalService {

    @Value("${basic.maxSequenceNoLength}")
    private Integer maxSequenceNoLength;
    @Value("${basic.adminId}")
    private String adminId;
    @Value("${basic.adminDeptId}")
    private String adminDeptId;
    @Value("${basic.hospitalUrl}")
    private String hospitalUrl;
    @Value("${basic.webServiceUsername}")
    private String webServiceUsername;
    @Value("${basic.webServicePassword}")
    private String webServicePassword;
    @Autowired
    private HEMSHospitalMapper hemsHospitalMapper;
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private DefaultTransactionDefinition defaultTransactionDefinition;

    @Override
    public int addOrUpdateHospital(int hours) {
        int num = 0;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.00");
        // 获取当前时间减去24小时之后的时间
        String dateTime = format.format(DateUtils.addDay(new Date(), 0 - hours));
        // 拼接hospitalUtl，参数加上时间
        String url = hospitalUrl + dateTime;
        // 获取最大单据号
        String sequenceNo = hemsHospitalMapper.selectMaxSequenceNo();
        if (StringUtils.isNullOrEmpty(sequenceNo)){
            num = ResultCode.init_error;
            return num;
        }
        Integer maxSequenceNo = Integer.valueOf(sequenceNo.substring(sequenceNo.length()-maxSequenceNoLength));
        log.info("请求webservice接口地址url：{}，需要认证的用户名信息：{}，需要认证的密码信息：{}", url, webServiceUsername, webServicePassword);
        // 请求webservice接口，获取医院信息
        String result = HttpClients.getByBasicAuth(url, webServiceUsername, webServicePassword);
        log.info("请求webservice返回结果：{}", JSON.parseObject(result));
        JSONArray hospitalList = new JSONArray();
        // 事务隔离级别，开启新事务
        defaultTransactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        // 手动开启事物
        TransactionStatus transactionStatus = null;
        try {
            transactionStatus = dataSourceTransactionManager.getTransaction(defaultTransactionDefinition);
            // result不为空时，说明请求到了数据
            if (!StringUtils.isNullOrEmpty(result)) {
                JSONObject jsonObject = JSON.parseObject(result);
                if (jsonObject.containsKey("data")) {
                    HEMSHospital insertHospital = new HEMSHospital();
                    HEMSHospital updateHospital = new HEMSHospital();
                    insertHospital.setCreater(adminId);
                    insertHospital.setModifier(adminId);
                    insertHospital.setOwner(adminId);
                    insertHospital.setOwner(adminId);
                    insertHospital.setCreateddeptid(adminDeptId);
                    insertHospital.setOwnerdeptid(adminDeptId);
                    insertHospital.setWorkflowinstanceid("");
                    insertHospital.setOwnerdeptquerycode("");
                    insertHospital.setSequencestatus("COMPLETED");
                    hospitalList.addAll(jsonObject.getJSONArray("data"));
                    JSONObject links = jsonObject.getJSONObject("links");
                    boolean next = links.getString("next") != null;
                    if (next) {
                        url = links.getString("next");
                    }
                    // 如果next值不为空，说明还有数据，则一直循环请求接口
                    while (next) {
                        log.info("请求webservice接口地址url：{}，需要认证的用户名信息：{}，需要认证的密码信息：{}", url, webServiceUsername, webServicePassword);
                        result = HttpClients.getByBasicAuth(url, webServiceUsername, webServicePassword);
                        log.info("请求webservice返回结果：{}", JSON.parseObject(result));
                        jsonObject = JSON.parseObject(result);
                        hospitalList.addAll(jsonObject.getJSONArray("data"));
                        links = jsonObject.getJSONObject("links");
                        if (links.getString("next") == null) {
                            next = false;
                        } else {
                            url = links.getString("next");
                        }
                    }
                    HEMSHospital hemsHospital = null;
                    // 遍历数据，进行添加或者更新
                    if (hospitalList.size() > 0) {
                        String year = DateUtils.getYear(new Date());
                        for (int i = 0; i < hospitalList.size(); i++) {
                            jsonObject = hospitalList.getJSONObject(i);
                            // 通过主键查询当前医院是否存在于数据库中，如果存在更新数据信息，不存在添加数据信息
                            hemsHospital = hemsHospitalMapper.selectByHospitalCode(jsonObject.getJSONObject("fields").getString("external_id"));
                            // 医院存在，数据更新
                            if (hemsHospital != null) {
                                updateHospital.setId(hemsHospital.getId());
                                updateHospital.setModifiedtime(new Timestamp(new Date().getTime()));
                                updateHospital.setHospitalname(jsonObject.getJSONObject("fields").getString("name"));
                                updateHospital.setHospitaltype(jsonObject.getJSONObject("fields").getJSONObject("hospital_type").getString("label"));
                                updateHospital.setHospitalalias(jsonObject.getJSONObject("fields").getString("alias"));
                                updateHospital.setHospitalgrade(jsonObject.getJSONObject("fields").getJSONObject("hospital_grade").getString("label"));
                                updateHospital.setProvince(jsonObject.getJSONObject("fields").getString("geo_province"));
                                updateHospital.setCity(jsonObject.getJSONObject("fields").getString("geo_city"));
                                updateHospital.setDistrict(jsonObject.getJSONObject("fields").getString("geo_district"));
                                updateHospital.setName(updateHospital.getHospitalname());
                                num = hemsHospitalMapper.updateByPrimaryKeySelective(updateHospital);
                                log.info("update isrv4_HEMS_Hospital，updateHospital：{}，result：{}", updateHospital, num);
                                if (num == 1) {
                                    num = 0;
                                } else {
                                    num = ResultCode.update_error;
                                    break;
                                }
                            } else {// 医院不存在，数据新增
                                insertHospital.setId(UUID.randomUUID().toString());
                                insertHospital.setCreatedtime(new Timestamp(new Date().getTime()));
                                insertHospital.setModifiedtime(insertHospital.getCreatedtime());
                                maxSequenceNo++;
                                insertHospital.setSequenceno(year + "-" + String.format("%0" + maxSequenceNoLength + "d", maxSequenceNo));
                                insertHospital.setHospitalcode(jsonObject.getJSONObject("fields").getString("external_id"));
                                insertHospital.setHospitalname(jsonObject.getJSONObject("fields").getString("name"));
                                insertHospital.setHospitaltype(jsonObject.getJSONObject("fields").getJSONObject("hospital_type").getString("label"));
                                insertHospital.setHospitalalias(jsonObject.getJSONObject("fields").getString("alias"));
                                insertHospital.setHospitalgrade(jsonObject.getJSONObject("fields").getJSONObject("hospital_grade").getString("label"));
                                insertHospital.setProvince(jsonObject.getJSONObject("fields").getString("geo_province"));
                                insertHospital.setCity(jsonObject.getJSONObject("fields").getString("geo_city"));
                                insertHospital.setDistrict(jsonObject.getJSONObject("fields").getString("geo_district"));
                                insertHospital.setName(insertHospital.getHospitalname());
                                num = hemsHospitalMapper.insertSelective(insertHospital);
                                log.info("insert isrv4_HEMS_Hospital，insertHospital：{}，result：{}", insertHospital, num);
                                if (num == 1) {
                                    num = 0;
                                } else {
                                    num = ResultCode.insert_error;
                                    break;
                                }
                            }
                        }
                        if (num == 0) {
                            dataSourceTransactionManager.commit(transactionStatus);
                        } else {
                            dataSourceTransactionManager.rollback(transactionStatus);
                        }
                        hospitalList = null;
                        insertHospital = null;
                        updateHospital = null;
                    }
                }
            }
        } catch (Exception e) {
            if (transactionStatus != null){
                dataSourceTransactionManager.rollback(transactionStatus);
            }
            num = ResultCode.network_error;
        }
        return num;
    }
}
